package org.jackysoft.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ClassUtils {
	protected static final Log log = LogFactory.getLog(ClassUtils.class);

	/**
	 * @author qujiakang
	 * @return Map 传入的javabean的map表示
	 * @param bean
	 *            具有键值对的javabean
	 */
	@SuppressWarnings("unchecked")
	public static Map parsePropertiesMap(Object bean) {

		PropertyUtilsBean pb = new PropertyUtilsBean();
		Map pros = new HashMap();
		try {
			pros.putAll(pb.describe(bean));
		} catch (IllegalAccessException e) {

			e.printStackTrace();
		} catch (InvocationTargetException e) {

			e.printStackTrace();
		} catch (NoSuchMethodException e) {

			e.printStackTrace();
		}
		return pros;

	}

	/**
	 * @author qujiakang 生成随机字符串 基本字符串:[abcdefghigklmnopqrstuvwxyz0123456789_$]
	 */
	// 默认长度为30
	private static int LENGTH = 30;

	private static final String base = "abcdefghigklmnopqrstuvwxyz0123456789";

	/**
	 * @author qujiakang
	 * @return 一个长度为30的随机字符串
	 */
	public static String generateRString() {
		char[] chs = new char[LENGTH];
		Random rd = new Random();
		for (int j = 0; j < LENGTH; j++)
			chs[j] = base.charAt(rd.nextInt(base.length() - 1));

		return new String(chs);
	}

	/**
	 * @author qujiakang
	 * @return 一个长度为len的随机字符串
	 * @param len
	 *            字符串长度
	 */
	public static String generateRString(int len) {
		char[] chs = new char[len];
		Random rd = new Random();
		for (int j = 0; j < len; j++)
			chs[j] = base.charAt(rd.nextInt(base.length() - 1));

		return new String(chs);
	}

	public static Object loadObjectFromBytes(byte[] bytes) {
		Object obj = null;
		if (bytes == null)
			return new HashMap();
		try {
			ByteArrayInputStream bys = new ByteArrayInputStream(bytes);
			ObjectInputStream oos = new ObjectInputStream(bys);
			obj = oos.readObject();
			// log.info(obj.getClass());
			oos.close();
			bys.close();
		} catch (IOException e) {

			e.printStackTrace();
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}

		return obj;

	}

	public static byte[] getBytesFromObject(Object o) {
		byte[] byteparam = null;
		try {
			ByteArrayOutputStream bys = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bys);
			oos.writeObject(o);
			byteparam = bys.toByteArray();
			oos.close();
			bys.close();

		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return byteparam;
	}

	public static String getResource(String fileName) {
		return new String(getResourceAsByteArray(fileName));
	}

	/**
	 * 从当前类路径里加载一个文件 返回字节数组的形式
	 */

	public static byte[] getResourceAsByteArray(String fileName) {
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		InputStream input = loader.getResourceAsStream(fileName);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		try {

			if (input == null)
				throw new FileNotFoundException("当前类路径里没有找到此文件 " + fileName);

			byte[] buf = new byte[1024];
			int b = 0;
			while ((b = input.read(buf)) != -1) {
				bos.write(buf, 0, b);
			}
			bos.close();
			input.close();
		} catch (Exception e) {

			e.printStackTrace();
		}

		return bos.toByteArray();
	}

	/**
	 * @param encoding
	 *            编码
	 * @param fileName
	 *            文件名
	 */
	public static String getResourceAsString(String fileName, String enc) {
		String s = null;
		try {
			s = new String(getResourceAsByteArray(fileName), enc);
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		}
		return s;
	}

	public static byte[] getResourceAsByteArray(String fileName, String enc) {
		byte[] bs = null;
		try {
			bs = new String(getResourceAsByteArray(fileName), enc)
					.getBytes(enc);
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		}
		return bs;
	}

	public static String encodePass(String pass) {
		byte[] ecd = new EncryptData2().encrypt(pass);
		StringBuffer sb = new StringBuffer(2 * ecd.length);
		for (byte b : ecd)
			sb.append(b).append(",");
		return sb.toString().trim();
	}

	public static String decodePass(String pass) {
		String[] srs = pass.split(",");
		byte[] shi = new byte[srs.length];
		for (int j = 0; j < srs.length; j++) {
			shi[j] = Byte.parseByte(srs[j]);
		}
		return new EncryptData2().decrypt(shi);
	}

	public static String getUTF8String(String str) {
		String strs = "";
		try {
			strs = new String(str.getBytes("gbk"), "utf-8");
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		}
		return strs;
	}

	/**
	 * @param str
	 *            数字字符串
	 * @return true 指定字符串是一个数字 不然返回false
	 */
	public static Boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("([0-9]*\\.[0-9]*)|([0-9]*)");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * 改变集合中元素的某个属性值
	 * 
	 * @author qujiakang
	 * @param Collection
	 *            c 要处理的集合
	 * @param Object
	 *            propertyName 要处理的属性名
	 * @see #org #
	 */
	public static void forAllDo(final Collection c, final Object propertyName) {
		CollectionUtils.forAllDo(c, new Closure() {

			@Override
			public void execute(Object arg0) {
				// TODO 自动生成方法存根
				Object newpro;
				try {
					newpro = PropertyUtils.getProperty(arg0,
							(String) propertyName);
					String s = new String(((String) newpro)
							.getBytes("iso8859-1"));
					PropertyUtils.setProperty(arg0, (String) propertyName, s);
				} catch (IllegalAccessException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (UnsupportedEncodingException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				}

			}

		});

	}

	/**
	 * @author qujiakang
	 * @param col
	 *            要改变的集合
	 * @param oldType
	 *            集合所包含的旧对象类型
	 * @param newType
	 *            集合所要改变的新对象类型
	 * @param asConparam
	 *            新对象是否把就对象作为构造参数
	 * @return 空
	 */
	public static void alterCollectionObject(final Collection col,
			final String oldType, final String newType, final boolean asConparam) {

		CollectionUtils.transform(col, new Transformer() {

			@Override
			public Object transform(Object arg0) {
				Object theObj = null;
				try {

					Object newobj = Class.forName(newType).newInstance();
					log.debug("新对象的名字 : " + newobj.getClass().getName());
					log.debug("就对象的名字 : " + arg0.getClass().getName());
					if (asConparam) {
						Constructor<? extends Object> contr = newobj
								.getClass()
								.getConstructor(new Class[] { arg0.getClass() });
						log.debug("构造函数名字 : " + contr.getClass().getName());
						Object obj = contr.newInstance(new Object[] { arg0 });
						log.debug("构造的新对象名字 : " + obj.getClass().getName());
						theObj = obj;
					} else {
						theObj = newobj;
					}
				} catch (InstantiationException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (SecurityException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO 自动生成 catch 块
					e.printStackTrace();
				}
				return theObj;
			}

		});

	}

	/**
	 * @param Collection
	 *            c 要检测的集合类型
	 * @return 集合类型
	 */

	public static String fectchCollectionType(Collection c) {
		String type = "Object";
		if (c != null && c.size() != 0) {
			Object obj = c.iterator().next();
			type = obj.getClass().getName();
		}
		return type;
	}

	/**
	 * 
	 * 
	 */
	@SuppressWarnings("unchecked")
	public static void copyList(Collection dest, Collection src) {

		dest.addAll(src);
	}

	public static Object copy(Object oldObj) {
		Object obj = null;
		try {

			// Write the object out to a byte array

			ByteArrayOutputStream bos = new ByteArrayOutputStream();

			ObjectOutputStream out = new ObjectOutputStream(bos);

			out.writeObject(oldObj);

			out.flush();

			out.close();

			// Retrieve an input stream from the byte array and read

			// a copy of the object back in.

			ByteArrayInputStream bis = new ByteArrayInputStream(
					bos.toByteArray());

			ObjectInputStream in = new ObjectInputStream(bis);

			obj = in.readObject();

		} catch (IOException e) {
			log.error(e);
			e.printStackTrace();

		} catch (ClassNotFoundException cnfe) {
			log.error(cnfe);
			cnfe.printStackTrace();

		}

		return obj;

	}

}